/**
 * For the license, see main.cpp file
 */

#include "NewsParser.h"

#define CONN_TIMEOUT 10000

/* Constructor */
NewsParser::NewsParser()
{
	rssUrls = new QMap<QString, QUrl>();
	
	rssUrls->insert("StudentiDIA.org Forum", QUrl("http://forum.studentidia.org/index.php?act=rssout&id=6", QUrl::StrictMode));
	rssUrls->insert("StudentiDIA.org Forum - Laurea Specialistica", QUrl("http://forum.studentidia.org/index.php?act=rssout&id=12", QUrl::StrictMode));
	rssUrls->insert("StudentiDIA.org Forum - Laurea Triennale", QUrl("http://forum.studentidia.org/index.php?act=rssout&id=11", QUrl::StrictMode));
	rssUrls->insert("StudentiDIA.org Forum - Discussioni Generali", QUrl("http://forum.studentidia.org/index.php?act=rssout&id=8", QUrl::StrictMode));
	rssUrls->insert("Dipartimento Ingegneria informatica", QUrl("http://didattica.dia.uniroma3.it/rss/rss.php", QUrl::StrictMode));
	rssUrls->insert("Dipartimento Matematica", QUrl("http://www.mat.uniroma3.it/news.xml", QUrl::StrictMode));
	//rssUrls->insert("Slux Site", QUrl("http://www.capponcino.it/alessio/rss_blog.php", QUrl::StrictMode));
}

/**
 * Collaterar effect (with signal emitted)
 */
void NewsParser::parseFeedRss(QUrl &rss)
{
	QString page = fetchHttpPage(rss);
	
	// local stuff
	QString title, link;
	FeedRSS *news = new FeedRSS();

	/* page is empty mean cottection error */
	if(page == "")
	{
		emit newsError("GET rss failed. Please retry.");
		return;
	}
	

	// remove http header
	QStringList pageSplitted = page.split("\r\n\r\n");
	pageSplitted.removeFirst();
	page = pageSplitted.join("");

	QDomDocument xmlDoc;
	QString msgError;
	int errRow, errCol;
	if(!xmlDoc.setContent(page, &msgError, &errRow, &errCol))
	{
		qWarning()	<< "Feed RSS" << rss.toString() << " NOT VALID. Dom error"
					<< msgError << "Line:" << errRow << "Column:" << errCol;
		//qDebug() << page;
		emit newsError("Feed RSS NOT VALID or NOT STANDARD!");
		return;
	}
	
	QDomNodeList channelChilds = xmlDoc.elementsByTagName("channel").at(0).childNodes();
	
	for(int i=0; i<channelChilds.size(); i++)
	{
		//rss title
		if(channelChilds.at(i).nodeName() == "title")
		{
			news->setFeedTitle(channelChilds.at(i).firstChild().toText().data());
		}
		
		//site link
		if(channelChilds.at(i).nodeName() == "link")
		{
			news->setFeedLink(channelChilds.at(i).firstChild().toText().data());
		}
		
		//site description
		if(channelChilds.at(i).nodeName() == "description")
		{
			news->setFeedDescription(channelChilds.at(i).firstChild().toText().data());
		}
		
		//news item
		if(channelChilds.at(i).nodeName() == "item")
		{
			// qDebug() << "---------------------------------";
			
			QDomNodeList itemChilds = channelChilds.at(i).childNodes();
			for(int j=0; j<itemChilds.size(); j++)
			{
				//the title item
				if(itemChilds.at(j).nodeName() == "title")
				{	
					
					// text node
					if(itemChilds.at(j).firstChild().nodeType() == QDomNode::TextNode)
					{
						//qDebug() << "titel:" << itemChilds.at(j).firstChild().toText().data();
						title = itemChilds.at(j).firstChild().toText().data();
					}
					
					// cdata node
					if(itemChilds.at(j).firstChild().nodeType() == QDomNode::CDATASectionNode)
					{
						//qDebug() << "title:" << itemChilds.at(j).firstChild().toCDATASection().data();
						title = itemChilds.at(j).firstChild().toCDATASection().data();
					}
				}
				
				//the item link
				if(itemChilds.at(j).nodeName() == "link")
				{
					// qDebug() << "link >>>" << itemChilds.at(j).firstChild().toText().data();
					link = itemChilds.at(j).firstChild().toText().data();
				}
			}
			//save entry
			news->getItems()->append(QPair<QString, QString>(title, link));
		}
	}
	
	xmlDoc.clear();
	emit newsReady(news);
}

void NewsParser::run()
{
	qDebug() << "News thread started.";
	parseFeedRss(currentUrl);
}

QString NewsParser::fetchHttpPage(QUrl &rss)
{
	QTcpSocket tcpSock;
	QString pageContent;
	tcpSock.connectToHost(rss.host(), rss.port(80));
	
	if(tcpSock.waitForConnected(CONN_TIMEOUT))
	{
		qDebug() << "connected to" << rss.toString();
	}
	else
	{
		qDebug() << rss.toString() << "Server unreachable";
		return pageContent;
	}
	
	qDebug() << "GET to" << rss.host() << rss.path() << rss.encodedQuery();

	/* get http */
	
	//attach the query string?
	if(!rss.encodedQuery().isEmpty())
		tcpSock.write("GET " + rss.path().toUtf8() + "?" + rss.encodedQuery() + " HTTP/1.0\r\n");
	else
		tcpSock.write("GET " + rss.path().toUtf8() + " HTTP/1.0\r\n");	
	tcpSock.write("Host: " + rss.host().toUtf8() + "\r\n");	
	tcpSock.write("User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.10) Gecko/20071201 BonEcho/2.0.0.10\r\n");
	tcpSock.write("Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5\r\n");
	tcpSock.write("Accept-Charset: iso-8859-1, utf-8;q=0.5, *;q=0.5\r\n");
	tcpSock.write("\r\n");
	tcpSock.flush();
	
	/* Read hole response */
	while(tcpSock.waitForReadyRead(CONN_TIMEOUT))
	{
		pageContent += tcpSock.readAll();
	}
	
	//tcpSock.close();
	
	if(!pageContent.contains("200 OK"))
		pageContent.clear();
	
	return pageContent;
}

/* Get rss urls */
QMap<QString, QUrl>* NewsParser::getRssUrls()
{
	return rssUrls;
}

/* Set current url te parse */
void NewsParser::setCurrentUrlAndStart(QString rssKey)
{
	currentUrl = rssUrls->value(rssKey);
	this->start();
}
